var util = require("./util"), sendBeacon = require("./common/sendBeacon"), selfId = "aokcdqn3ly@e629dabd48a9933", pushToQueue = function(e, t) {
    var r;
    {
        if ("error" !== t.t || !(r = e.requestQueue[0]) || "error" !== r.t || t.msg !== r.msg) {
            if ("behavior" === t.t) {
                var i = e.requestQueue && e.requestQueue.length;
                if (i > 0 && "behavior" === e.requestQueue[i - 1].t) {
                    var n = t.behavior || [];
                    e.requestQueue[i - 1].behavior.concat(n);
                } else e.requestQueue.push(t);
            } else e.requestQueue.unshift(t);
            return e.onReady(function() {
                e.requestTimmer = util.delay(function() {
                    e.clear();
                }, e.requestQueue[0] && "error" === e.requestQueue[0].t ? 3e3 : -1);
            }), !0;
        }
        r.times++;
    }
}, Base = function(e) {
    return this.ver = "1.8.27", this._conf = util.ext({}, Base.dftCon), this.sampleCache = {}, 
    this.requestQueue = [], this.selfQueue = [], this.sdkFlag = !0, this.hash = util.seq(), 
    this.resetPageview(), this.setConfig(e), this.rip = util.getRandIP(), this.record = 999, 
    this["EagleEye-TraceID"] = this.getTraceId()["EagleEye-TraceID"], this._common = {}, 
    this;
};

Base.dftCon = {
    sample: 1,
    pvSample: 1,
    tag: "",
    imgUrl: "https://arms-retcode.aliyuncs.com/r.png?",
    region: null,
    ignore: {
        ignoreUrls: [],
        ignoreApis: [],
        ignoreErrors: [ /^Script error\.?$/ ],
        ignoreResErrors: []
    },
    release: undefined,
    environment: "prod"
}, Base.prototype = {
    constructor: Base,
    onReady: function(e) {
        return e();
    },
    getPage: function() {
        var e = this._conf.page;
        return util.safetyCall(e, [], e + "");
    },
    setPage: function() {},
    setConfig: function(e) {
        e && "object" == typeof e && (util.verifyConfig(e), e = this.setImgUrl(e), this._conf = util.ext({}, this._conf, e));
    },
    setImgUrl: function(e) {
        var t = e.region, r = e.imgUrl;
        if (t) {
            var i = util.regionMap[t];
            return e.imgUrl = i || util.defaultImgUrl, e;
        }
        return r && (e.imgUrl = r), e;
    },
    checkImgUrl: function(e) {
        if (this.getConfig("debug")) return !0;
        var t = util.regionMap, r = !1;
        for (var i in t) if (t[i] === e) {
            r = !0;
            break;
        }
        return !r && util.warn("[retcode] invalid url: " + e), r;
    },
    sendRequest: function() {},
    sendBeacon: function(e) {
        sendBeacon(e, this.getConfig("imgUrl"));
    },
    postData: function() {},
    commonInfo: function() {
        return {};
    },
    setCommonInfo: function(e) {
        e && "object" == typeof e && (this._common = util.ext({}, this._common, e));
    },
    resetPageview: function() {
        this.pageview = util.uu(), this.sBegin = Date.now();
    },
    getUsername: function() {
        if (this.username) return this.username;
        var e = this._conf, t = e && e.setUsername;
        if ("function" == typeof t) try {
            var r = t();
            "string" == typeof r && (r = r.substr(0, 20), this.username = r);
        } catch (i) {
            util.warn("[arms] setUsername fail", i);
        }
        return this.username;
    },
    getTraceId: function() {
        var e = this.rip, t = Date.now(), r = util.getSortNum(this.record), i = e + t + r + util.getRandNum(this._conf.pid);
        return this["EagleEye-TraceID"] = i, this.record = r, {
            "EagleEye-TraceID": i
        };
    },
    getUberTraceId: function(e) {
        var t = this.rip, r = Date.now(), i = util.getSortNum(this.record), n = util.getRandNum(this._conf.pid), s = t + r + i + util.getNum(2) + n, u = s.substring(0, 16);
        return e = e ? "1" : "0", {
            "uber-trace-id": s + ":" + u + ":0:" + e,
            traceId: s
        };
    },
    getPageviewId: function() {
        return {
            "EagleEye-SessionID": this.pageview
        };
    },
    getConfig: function(e) {
        return e ? this._conf[e] : util.ext({}, this._conf);
    },
    sampling: function(e) {
        return 1 === e || ("boolean" == typeof this.sampleCache[e] ? this.sampleCache[e] : (this.sampleCache[e] = util.pick(e), 
        this.sampleCache[e]));
    },
    clear: function(e) {
        var t;
        clearTimeout(this.requestTimmer), this.requestTimmer = null;
        for (var r = this._conf && "function" == typeof this._conf.sendRequest; t = this.requestQueue.pop(); ) "res" === t.t ? this.postData(t, "res") : "error" === t.t ? this.postData(t, "err") : "api" === t.t ? this.postData(t, "apiSnapshot") : "behavior" === t.t ? this.postData(t, "behavior") : "health" === t.t && !r && window && window.navigator && "function" == typeof window.navigator.sendBeacon ? this.sendBeacon(t) : this.sendRequest(t);
        return e && this.clearSelf(), this;
    },
    clearSelf: function() {
        var e;
        for (clearTimeout(this.Timmer), this.Timmer = null; e = this.selfQueue.pop(); ) this.postData(e, "err");
        return this;
    },
    _lg: function(e, t, r, i) {
        var n = this._conf, s = this.getPage(), u = n.ignore || {}, o = u.ignoreErrors, a = u.ignoreResErrors, l = u.ignoreUrls, c = u.ignoreApis;
        if (this._isRobot) return this;
        if (util.ignoreByRule(s, l) || util.ignoreByRule(util.decode(s), l)) return this;
        if ("error" === e && (util.ignoreByRule(t.msg, o) || util.ignoreByRule(util.decode(t.msg), o))) return this;
        if ("resourceError" === e && (util.ignoreByRule(t.src, a) || util.ignoreByRule(util.decode(t.src), a))) return this;
        if ("api" === e && (util.ignoreByRule(t.api, c) || util.ignoreByRule(util.decode(t.api), c))) return this;
        if (!this.checkImgUrl(n.imgUrl)) return this;
        if (!t || n.disabled || !n.pid) return this;
        if (0 === i) return this;
        var h = t.dl;
        return delete t.dl, t = util.ext({
            t: e,
            times: 1,
            page: s,
            tag: n.tag || "",
            release: n.release || "",
            environment: n.environment,
            begin: Date.now(),
            c1: n.c1,
            c2: n.c2,
            c3: n.c3
        }, t, this.commonInfo(), this._common, {
            pid: n.pid,
            _v: this.ver,
            pv_id: this.pageview,
            username: this.getUsername(),
            sampling: r || 1,
            dl: h,
            z: util.seq()
        }), 1 === i ? pushToQueue(this, t) : r && !this.sampling(r) ? this : pushToQueue(this, t);
    },
    _self: function(e, t, r) {
        var i = this, n = i._conf;
        if ("error" !== e) return i;
        if (!i.checkImgUrl(n.imgUrl)) return i;
        if (!t || n.disabled || !n.pid || !selfId) return i;
        if (r && !i.sampling(r)) return i;
        t = util.ext({
            t: e,
            times: 1,
            page: util.selfErrPage,
            tag: n.pid,
            begin: Date.now()
        }, t, {
            pid: selfId,
            _v: i.ver,
            sampling: r || 1,
            z: util.seq()
        });
        var s = i.selfQueue[0];
        if (s) {
            s.times++;
            try {
                if (s.err && t.err && s.err.msg_raw && t.err.msg_raw) {
                    s.err.msg_raw.split("&").indexOf(t.err.msg_raw) < 0 && s.err.msg_raw.length < 1e3 && (s.err.msg_raw += "&" + t.err.msg_raw);
                }
            } catch (u) {}
        } else i.selfQueue.unshift(t), i.onReady(function() {
            i.sdkFlag && (i.sdkFlag = !1, i.Timmer = util.delay(function() {
                i.clearSelf();
            }, 1e4));
        });
    },
    custom: function(e, t) {
        if (!e || "object" != typeof e) return this;
        var r = !1, i = {
            begin: Date.now()
        };
        return util.each(e, function(e, t) {
            return !(r = t && t.length <= 20) && util.warn("[retcode] invalid key: " + t), i["x-" + t] = e, 
            r;
        }), r ? this._lg("custom", i, t || 1) : this;
    }
}, module.exports = Base;